home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / DEMON / GNU / PDMake / c / input < prev    next >
Text File  |  1992-12-08  |  7KB  |  348 lines

  1. /* > c.Input
  2.  *
  3.  * $Id: c.input 1.4 95/04/19 22:44:35 root Rel $
  4.  *
  5.  * $Log:    c.input $
  6.  * Revision 1.4  95/04/19  22:44:35  root
  7.  * Checked in for release
  8.  * 
  9.  * Revision 1.3  95/04/18  21:47:06  root
  10.  * *** empty log message ***
  11.  * 
  12.  * Revision 1.2  95/04/18  21:42:02  root
  13.  * Tidied for release
  14.  * 
  15.  *
  16.  * Parse a makefile
  17.  */
  18.  
  19.  
  20. #include <stdio.h>
  21. #include "h.h"
  22.  
  23.  
  24. struct name  namehead;
  25. struct name *  firstname;
  26.  
  27. char    str1[LZ];  /*   General store  */
  28. char   str2[LZ];
  29.  
  30.  
  31. /*
  32.  * Intern a name.  Return a pointer to the name struct
  33.  */
  34. struct name *
  35. newname(char * name)
  36. {
  37.  register struct name * rp;
  38.  register struct name * rrp;
  39.  register char *  cp;
  40.  
  41.  
  42.  for
  43.  (
  44.   rp = namehead.n_next, rrp = &namehead;
  45.   rp;
  46.   rp = rp->n_next, rrp = rrp->n_next
  47.  )
  48.   if (strcmp(name, rp->n_name) == 0)
  49.    return rp;
  50.  
  51.  if ((rp = (struct name *)malloc(sizeof (struct name)))
  52.     == (struct name *)0)
  53.   fatal("No memory for name");
  54.  rrp->n_next = rp;
  55.  rp->n_next = (struct name *)0;
  56.  if ((cp = malloc(strlen(name)+1)) == (char *)0)
  57.   fatal("No memory for name");
  58.  strcpy(cp, name);
  59.  rp->n_name = cp;
  60.  rp->n_line = (struct line *)0;
  61.  rp->n_time = (time_t)0;
  62.  rp->n_flag = 0;
  63.  
  64.  return rp;
  65. }
  66.  
  67.  
  68. /*
  69.  * Add a dependant to the end of the supplied list of dependants.
  70.  * Return the new head pointer for that list.
  71.  */
  72. struct depend *
  73. newdep(struct name * np,struct depend * dp)
  74.  
  75. {
  76.  register struct depend * rp;
  77.  register struct depend * rrp;
  78.  
  79.  
  80.  if ((rp = (struct depend *)malloc(sizeof (struct depend)))
  81.     == (struct depend *)0)
  82.   fatal("No memory for dependant");
  83.  rp->d_next = (struct depend *)0;
  84.  rp->d_name = np;
  85.  
  86.  if (dp == (struct depend *)0)
  87.   return rp;
  88.  
  89.  for (rrp = dp; rrp->d_next; rrp = rrp->d_next)
  90.   ;
  91.  
  92.  rrp->d_next = rp;
  93.  
  94.  return dp;
  95. }
  96.  
  97.  
  98. /*
  99.  * Add a command to the end of the supplied list of commands.
  100.  * Return the new head pointer for that list.
  101.  */
  102. struct cmd *
  103. newcmd(char * str, struct cmd * cp)
  104.  
  105. {
  106.  register struct cmd * rp;
  107.  register struct cmd * rrp;
  108.  register char *  rcp;
  109.  
  110.  
  111.  if (rcp = rindex(str, '\n'))
  112.   *rcp = '\0';  /*  Loose newline  */
  113.  
  114.  while (isspace(*str))
  115.   str++;
  116.  
  117.  if (*str == '\0')  /*  If nothing left, the exit  */
  118.   return 0 ;
  119.  
  120.  if ((rp = (struct cmd *)malloc(sizeof (struct cmd)))
  121.     == (struct cmd *)0)
  122.   fatal("No memory for command");
  123.  rp->c_next = (struct cmd *)0;
  124.  if ((rcp = malloc(strlen(str)+1)) == (char *)0)
  125.   fatal("No memory for command");
  126.  strcpy(rcp, str);
  127.  rp->c_cmd = rcp;
  128.  
  129.  if (cp == (struct cmd *)0)
  130.   return rp;
  131.  
  132.  for (rrp = cp; rrp->c_next; rrp = rrp->c_next)
  133.   ;
  134.  
  135.  rrp->c_next = rp;
  136.  
  137.  return cp;
  138. }
  139.  
  140.  
  141. /*
  142.  * Add a new 'line' of stuff to a target.  This check to see
  143.  * if commands already exist for the target.  If flag is set,
  144.  * the line is a double colon target.
  145.  *
  146.  * Kludges:
  147.  * i)  If the new name begins with a '.', and there are no dependents,
  148.  *     then the target must cease to be a target.  This is for .SUFFIXES.
  149.  * ii) If the new name begins with a '.', with no dependents and has
  150.  *     commands, then replace the current commands.  This is for
  151.  *     redefining commands for a default rule.
  152.  * Neither of these free the space used by dependents or commands,
  153.  * since they could be used by another target.
  154.  */
  155. void
  156. newline(struct name * np,
  157.         struct depend *dp,
  158.         struct cmd * cp,
  159.         int flag)
  160.  
  161. {
  162.  bool   hascmds = FALSE;  /*  Target has commands  */
  163.  register struct line * rp;
  164.  register struct line * rrp;
  165.  
  166.  
  167.  /* Handle the .SUFFIXES case */
  168.  if (np->n_name[0] == '.' && !dp && !cp)
  169.  {
  170.   for (rp = np->n_line; rp; rp = rrp)
  171.   {
  172.    rrp = rp->l_next;
  173.    free(rp);
  174.   }
  175.   np->n_line = (struct line *)0;
  176.   np->n_flag &= ~N_TARG;
  177.   return;
  178.  }
  179.  
  180.  /* This loop must happen since rrp is used later. */
  181.  for
  182.  (
  183.   rp = np->n_line, rrp = (struct line *)0;
  184.   rp;
  185.   rrp = rp, rp = rp->l_next
  186.  )
  187.   if (rp->l_cmd)
  188.    hascmds = TRUE;
  189.  
  190.  if (hascmds && cp && !(np->n_flag & N_DOUBLE))
  191.   {
  192.   /* Handle the implicit rules redefinition case */
  193.   if (np->n_name[0] == '.' && dp == (struct depend *)0)
  194.    {
  195.    np->n_line->l_cmd = cp;
  196.    return;
  197.    }
  198.   else
  199.    report_error("Commands defined twice for target %s", np->n_name);
  200.   };
  201.  
  202.  if (np->n_flag & N_TARG)
  203.   if (!(np->n_flag & N_DOUBLE) != !flag)  /* like xor */
  204.    report_error("Inconsistent rules for target %s", np->n_name);
  205.  
  206.  if ((rp = (struct line *)malloc(sizeof (struct line)))
  207.     == (struct line *)0)
  208.   fatal("No memory for line");
  209.  rp->l_next = (struct line *)0;
  210.  rp->l_dep = dp;
  211.  rp->l_cmd = cp;
  212.  
  213.  if (rrp)
  214.   rrp->l_next = rp;
  215.  else
  216.   np->n_line = rp;
  217.  
  218.  np->n_flag |= N_TARG;
  219.  if (flag)
  220.   np->n_flag |= N_DOUBLE;
  221. }
  222.  
  223.  
  224. /*
  225.  * Parse input from the makefile, and construct a tree structure
  226.  * of it.
  227.  */
  228. void
  229. input(FILE *fd)
  230.  
  231. {
  232.  char *   p;  /*  General  */
  233.  char *   q;
  234.  struct name *  np;
  235.  struct depend *  dp;
  236.  struct cmd *  cp;
  237.  bool   dbl;
  238.  
  239.  
  240.  if (getline(str1, fd)) /*  Read the first line  */
  241.   return;
  242.  
  243.  for(;;)
  244.  {
  245.  
  246.   if (*str1 == '\t') /*  Rules without targets  */
  247.    report_error("Rules not allowed here");
  248.  
  249.   p = str1;
  250.  
  251.   while (isspace(*p)) /*  Find first target  */
  252.    p++;
  253.  
  254.   while (((q = index(p, '=')) != (char *)0) &&
  255.       (p != q) && (q[-1] == '\\')) /*  Find value */
  256.   {
  257.    register char *  a;
  258.  
  259.    a = q - 1; /*  Del \ chr; move rest back  */
  260.    p = q;
  261.    while(*a++ = *q++)
  262.     ;
  263.   }
  264.  
  265.   if (q != (char *)0)
  266.   {
  267.    register char *  a;
  268.  
  269.    *q++ = '\0';  /*  Separate name and val  */
  270.    while (isspace(*q))
  271.     q++;
  272.    if (p = rindex(q, '\n'))
  273.     *p = '\0';
  274.  
  275.    p = str1;
  276.    if ((a = gettok(&p)) == (char *)0)
  277.     report_error("No macro name");
  278.  
  279.    setmacro(a, q);
  280.  
  281.    if (getline(str1, fd))
  282.     return;
  283.     continue;
  284.   }
  285.  
  286.   expand(str1);
  287.   p = str1;
  288.  
  289.   while (((q = index(p, ':')) != (char *)0) &&
  290.       (p != q) && (q[-1] == '\\')) /*  Find dependents  */
  291.   {
  292.    register char *  a;
  293.  
  294.    a = q - 1; /*  Del \ chr; move rest back  */
  295.    p = q;
  296.    while(*a++ = *q++)
  297.     ;
  298.   }
  299.  
  300.   if (q == (char *)0)
  301.   report_error("No targets provided");
  302.  
  303.   *q++ = '\0'; /*  Separate targets and dependents  */
  304.  
  305.   if (*q == ':')  /* Double colon */
  306.   {
  307.    dbl = 1;
  308.    q++;
  309.   }
  310.   else
  311.    dbl = 0;
  312.  
  313.   for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
  314.      /*  get list of dep's */
  315.   {
  316.    np = newname(p);  /*  Intern name  */
  317.    dp = newdep(np, dp);  /*  Add to dep list */
  318.   }
  319.  
  320.   *((q = str1) + strlen(str1) + 1) = '\0';
  321.    /*  Need two nulls for gettok (Remember separation)  */
  322.  
  323.   cp = (struct cmd *)0;
  324.   if (getline(str2, fd) == FALSE)  /*  Get commands  */
  325.   {
  326.    while (*str2 == '\t')
  327.    {
  328.     cp = newcmd(&str2[0], cp);
  329.     if (getline(str2, fd))
  330.      break;
  331.    }
  332.   }
  333.  
  334.   while ((p = gettok(&q)) != (char *)0) /* Get list of targ's */
  335.   {
  336.    np = newname(p);  /*  Intern name  */
  337.    newline(np, dp, cp, dbl);
  338.    if (!firstname && p[0] != '.')
  339.     firstname = np;
  340.   }
  341.  
  342.   if (feof(fd))    /*  EOF?  */
  343.    return;
  344.  
  345.   strcpy(str1, str2);
  346.  }
  347. }
  348.